package org.daochong.web.filter;

import java.io.IOException;
import java.lang.reflect.Method;
import java.util.Locale;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.daochong.lang.LocaleContext;
import org.daochong.lang.Message;
import org.daochong.lang.session.SessionContextFactory;
import org.daochong.web.HttpResponseWrapper;
import org.daochong.web.Resources;
import org.daochong.web.SessionRequestWrapper;
import org.daochong.web.WebContext;
import org.daochong.web.WebUtils;

public class DaochongFilter implements Filter {

	private Method method = null;
	private boolean wrapperResponse;

	public void init(FilterConfig filterConfig) throws ServletException {
		try {
			Method m = WebContext.class.getDeclaredMethod("setServletContext", ServletContext.class);
			m.setAccessible(true);
			m.invoke(null, filterConfig.getServletContext());
			m.setAccessible(false);
			method = WebContext.class.getDeclaredMethod("setContext", HttpServletRequest.class,
					HttpServletResponse.class, String.class);
			method.setAccessible(true);
			if (filterConfig.getInitParameter("wrapperResponse") != null) {
				this.wrapperResponse = "true".equalsIgnoreCase(filterConfig.getInitParameter("wrapperResponse"));
			}
		} catch (Exception e) {
			e.printStackTrace();
		}

	}

	public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain)
			throws IOException, ServletException {
		HttpServletRequest request = (HttpServletRequest) req;
		String ct = request.getContentType();
		HttpServletResponse response = (HttpServletResponse) resp;
		if (this.wrapperResponse && (ct == null || !ct.startsWith("multipart"))) {
			response = new HttpResponseWrapper((HttpServletResponse) resp);
		}

		if (SessionContextFactory.getInstance() != null) {
			request = new SessionRequestWrapper(request, response);
		}
		String skin = request.getParameter(WebContext.SKIN_ID);
		if (skin == null) {
			Object o = request.getSession().getAttribute(WebContext.SKIN_ID);
			if (o != null && o instanceof String) {
				skin = (String) o;
			}
		}
		if (skin == null) {
			skin = WebUtils.getCookies(WebContext.SKIN_ID, request);
		}
		if (skin != null) {
			request.getSession().setAttribute(WebContext.SKIN_ID, skin);
		}
		try {
			method.invoke(null, request, response, skin);
		} catch (Throwable e) {
			e.printStackTrace();
		}

		String locale = request.getParameter(WebContext.LOCALE_ID);
		if (locale == null) {
			Object o = request.getSession().getAttribute(WebContext.LOCALE_ID);
			if (o != null && o instanceof String) {
				locale = (String) o;
			}
		}
		if (locale == null) {
			locale = WebUtils.getCookies(WebContext.LOCALE_ID, request);
		}
		if (locale == null) {
			locale = "zh_CN";
			WebUtils.setCookies(WebContext.LOCALE_ID, locale, 86400 * 365, true, false, response);
		}
		if (locale != null) {
			int pos = locale.indexOf("_");
			Locale loc;
			if (pos == -1) {
				loc = new Locale(locale);
			} else {
				loc = new Locale(locale.substring(0, pos), locale.substring(pos + 1));
			}
			LocaleContext.setLocale(loc);
		}
		String token = WebUtils.getToken(request, response);

		request.setAttribute(WebContext.MESSAGE_ID, Message.getInstance());
		request.setAttribute(WebContext.RESOURCES_ID, Resources.getInstance());
		request.setAttribute(WebUtils.TOKEN, token);
		request.setAttribute("WebRoot", WebContext.getContextPath());
		request.setAttribute("WebHost", WebContext.getHost());
		request.setAttribute("WebHostRoot", WebContext.getHost() + WebContext.getContextPath());
		request.setAttribute("skin", skin);
		chain.doFilter(request, response);

	}

	public void destroy() {

	}

}
